// 请求记录接口
interface RequestRecord {
  id: string;
  type: 'xhr' | 'fetch';
  method: string;
  url: string;
  requestHeaders: Record<string, string>;
  requestBody?: any;
  responseStatus?: number;
  responseHeaders?: Record<string, string>;
  responseBody?: any;
  startTime: number;
  endTime?: number;
  duration?: number;
  success?: boolean;
}

/**
 * @description 网络记录器类
 */
class NetworkLogger {
  private maxRecords: number;
  private records: RequestRecord[] = [];
  private originalXHR: any;
  private originalFetch: any;
  private eventListeners: Record<string, Function[]> = {};

  constructor(maxRecords: number = 10) {
    this.maxRecords = maxRecords;
    this.originalXHR = window.XMLHttpRequest;
    this.originalFetch = window.fetch;
    this.interceptXHR();
    this.interceptFetch();
  }

  /**
   * @description 拦截XMLHttpRequest
   */
  private interceptXHR() {
    const self = this;
    window.XMLHttpRequest = function() {
      const xhr = new self.originalXHR();
      const record: RequestRecord = {
        id: Math.random().toString(36).substr(2, 9),
        type: 'xhr',
        method: '',
        url: '',
        requestHeaders: {},
        startTime: Date.now(),
      };

      // 拦截open方法
      const originalOpen = xhr.open;
      xhr.open = function(method: string, url: string) {
        record.method = method;
        record.url = url;
        return originalOpen.apply(xhr, arguments as any);
      };

      // 拦截setRequestHeader方法
      const originalSetHeader = xhr.setRequestHeader;
      xhr.setRequestHeader = function(header: string, value: string) {
        record.requestHeaders[header] = value;
        return originalSetHeader.apply(xhr, arguments as any);
      };

      // 拦截send方法
      const originalSend = xhr.send;
      xhr.send = function(body?: any) {
        if (body) {
          try {
            if (typeof body === 'string') {
              record.requestBody = body;
            } else if (body instanceof FormData) {
              const formData: Record<string, any> = {};
              body.forEach((value, key) => {
                formData[key] = value;
              });
              record.requestBody = formData;
            } else {
              record.requestBody = body;
            }
          } catch (e) {
            record.requestBody = '<unable to parse>';
          }
        }
        
        self.addRecord(record);
        
        // 监听响应
        xhr.addEventListener('loadend', function() {
          record.endTime = Date.now();
          record.duration = record.endTime - record.startTime;
          record.responseStatus = xhr.status;
          record.success = xhr.status >= 200 && xhr.status < 300;
          
          try {
            record.responseHeaders = self.parseHeaders(xhr.getAllResponseHeaders());
            
            if (xhr.responseType === '' || xhr.responseType === 'text') {
              record.responseBody = xhr.responseText;
            } else if (xhr.responseType === 'json') {
              record.responseBody = xhr.response;
            } else {
              record.responseBody = `<${xhr.responseType} response>`;
            }
          } catch (e) {
            record.responseBody = '<unable to parse>';
          }
          
          self.updateRecord(record);
        });
        
        return originalSend.apply(xhr, arguments as any);
      };

      return xhr;
    } as any;
  }

  /**
   * @description 拦截Fetch API
   */
  private interceptFetch() {
    const self = this;
    // @ts-ignore
    window.fetch = function(input: RequestInfo, init?: RequestInit) {
      const url = typeof input === 'string' ? input : input.url;
      const method = init?.method || 'GET';
      
      const record: RequestRecord = {
        id: Math.random().toString(36).substr(2, 9),
        type: 'fetch',
        method,
        url,
        requestHeaders: {},
        requestBody: init?.body,
        startTime: Date.now(),
      };
      
      // 处理请求头
      if (init?.headers) {
        if (init.headers instanceof Headers) {
          init.headers.forEach((value, key) => {
            record.requestHeaders[key] = value;
          });
        } else if (Array.isArray(init.headers)) {
          init.headers.forEach(([key, value]) => {
            record.requestHeaders[key] = value;
          });
        } else {
          Object.entries(init.headers).forEach(([key, value]) => {
            record.requestHeaders[key] = value;
          });
        }
      }
      
      self.addRecord(record);
      
      return self.originalFetch(input, init).then(async (response: Response) => {
        const clone = response.clone();
        record.endTime = Date.now();
        record.duration = record.endTime - record.startTime;
        record.responseStatus = response.status;
        record.success = response.ok;
        
        // 处理响应头
        record.responseHeaders = {};
        clone.headers.forEach((value, key) => {
          if(record.responseHeaders) {
            record.responseHeaders[key] = value;
          }
        });
        
        // 处理响应体
        try {
          const contentType = response.headers.get('content-type') || '';
          if (contentType.includes('application/json')) {
            record.responseBody = await clone.json();
          } else if (contentType.includes('text/')) {
            record.responseBody = await clone.text();
          } else {
            record.responseBody = `<${contentType.split(';')[0]} response>`;
          }
        } catch (e) {
          record.responseBody = '<unable to parse>';
        }
        
        self.updateRecord(record);
        return response;
      }).catch((error: any) => {
        record.endTime = Date.now();
        record.duration = record.endTime - record.startTime;
        record.success = false;
        record.responseBody = error.message;
        self.updateRecord(record);
        throw error;
      });
    };
  }

  // 添加记录
  private addRecord(record: RequestRecord) {
    // 如果达到最大记录数，移除最旧的一条
    if (this.records.length >= this.maxRecords) {
      this.records.shift();
    }
    
    this.records.push(record);
    this.emit('recordAdded', record);
  }

  // 更新记录
  private updateRecord(record: RequestRecord) {
    this.emit('recordUpdated', record);
  }

  // 解析响应头
  private parseHeaders(headerString: string): Record<string, string> {
    const headers: Record<string, string> = {};
    if (!headerString) return headers;
    
    headerString.split('\r\n').forEach(line => {
      const [key, value] = line.split(': ');
      if (key) headers[key] = value;
    });
    
    return headers;
  }

  // 获取所有记录
  getRecords(): RequestRecord[] {
    return [...this.records];
  }

  // 清除所有记录
  clearRecords() {
    this.records = [];
    this.emit('recordsCleared');
  }

  // 事件监听
  on(event: string, listener: Function) {
    if (!this.eventListeners[event]) {
      this.eventListeners[event] = [];
    }
    this.eventListeners[event].push(listener);
  }

  // 事件触发
  private emit(event: string, ...args: any[]) {
    const listeners = this.eventListeners[event];
    if (listeners) {
      listeners.forEach(listener => listener(...args));
    }
  }
}

export default NetworkLogger;